From 3d4dd64808a9b1ffe34abd641767965fa304879b Mon Sep 17 00:00:00 2001 From: robertl Date: Wed, 11 Jan 2006 07:08:33 +0000 Subject: [PATCH] Add 'modifier' argument to [IO] field in xcsv. Initially define 'absolute" and "no_delim_before". git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@1687 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/csv_util.c | 52 +++++++++++++++++++++---------------- gpsbabel/csv_util.h | 5 +++- gpsbabel/style/README.style | 13 ++++++++-- gpsbabel/xcsv.c | 12 ++++++++- 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c index e7299f667..ba3b55a83 100644 --- a/gpsbabel/csv_util.c +++ b/gpsbabel/csv_util.c @@ -581,13 +581,14 @@ xcsv_ifield_add(char *key, char *val, char *pfc) /* usage: xcsv_ofield_add("LAT_DECIMAL", "", "%08.5lf") */ /*****************************************************************************/ void -xcsv_ofield_add(char *key, char *val, char *pfc) +xcsv_ofield_add(char *key, char *val, char *pfc, int options) { field_map_t *fmp = xcalloc(sizeof(*fmp), 1); fmp->key = key; fmp->val = val; fmp->printfc = pfc; + fmp->options = options; ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); xcsv_file.ofield_ct++; @@ -1103,10 +1104,17 @@ xcsv_waypt_pr(const waypoint *wpt) QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { char *obuff; fmp = (field_map_t *) elem; + double lat = wpt->latitude; + double lon = wpt->longitude; - if (i != 0) + if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) fprintf (xcsv_file.xcsvfp, write_delimiter); + if (fmp->options & OPTIONS_ABSOLUTE) { + lat = fabs(lat); + lon = fabs(lon); + } + i++; #define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) if (strcmp(fmp->key, "IGNORE") == 0) { @@ -1180,76 +1188,76 @@ xcsv_waypt_pr(const waypoint *wpt) /* LATITUDE CONVERSION***********************************************/ if (strcmp(fmp->key, "LAT_DECIMAL") == 0) { /* latitude as a pure decimal value */ - writebuff(buff, fmp->printfc, wpt->latitude); + writebuff(buff, fmp->printfc, lat); } else if (strcmp(fmp->key, "LAT_DECIMALDIR") == 0) { /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, fabs(wpt->latitude), - LAT_DIR(wpt->latitude)); + snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), + LAT_DIR(lat)); } else if (strcmp(fmp->key, "LAT_DIRDECIMAL") == 0) { /* latitude as a decimal value with N/S before it */ snprintf(buff, sizeof(buff), fmp->printfc, - LAT_DIR(wpt->latitude), - fabs(wpt->latitude)); + LAT_DIR(lat), + fabs(lat)); } else if (strcmp(fmp->key, "LAT_INT32DEG") == 0) { /* latitude as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(wpt->latitude, 1)); + dec_to_intdeg(lat, 1)); } else if (strcmp(fmp->key, "LAT_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "SN", wpt->latitude ); + dec_to_human( buff, fmp->printfc, "SN", lat ); } else if (strcmp(fmp->key, "LAT_NMEA") == 0) { - writebuff(buff, fmp->printfc, degrees2ddmm(wpt->latitude)); + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); } else /* LONGITUDE CONVERSIONS*********************************************/ if (strcmp(fmp->key, "LON_DECIMAL") == 0) { /* longitude as a pure decimal value */ - writebuff(buff, fmp->printfc, wpt->longitude); + writebuff(buff, fmp->printfc, lon); } else if (strcmp(fmp->key, "LON_DECIMALDIR") == 0) { /* latitude as a decimal value with N/S after it */ snprintf(buff, sizeof(buff), fmp->printfc, - fabs(wpt->longitude), - LON_DIR(wpt->longitude)); + fabs(lon), + LON_DIR(lon)); } else if (strcmp(fmp->key, "LON_DIRDECIMAL") == 0) { /* latitude as a decimal value with N/S before it */ snprintf(buff, sizeof(buff), fmp->printfc, - LON_DIR(wpt->longitude), - fabs(wpt->longitude)); + LON_DIR(lon), + fabs(lon)); } else if (strcmp(fmp->key, "LON_INT32DEG") == 0) { /* longitudee as an integer offset from 0 degrees */ writebuff(buff, fmp->printfc, - dec_to_intdeg(wpt->longitude, 0)); + dec_to_intdeg(lon, 0)); } else if (strcmp(fmp->key, "LON_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "WE", wpt->longitude ); + dec_to_human( buff, fmp->printfc, "WE", lon ); } else if (strcmp(fmp->key, "LATLON_HUMAN_READABLE") == 0) { - dec_to_human( buff, fmp->printfc, "SN", wpt->latitude ); + dec_to_human( buff, fmp->printfc, "SN", lat ); if ( !isspace(buff[strlen(buff)])) strcat( buff, " " ); dec_to_human( buff+strlen(buff), fmp->printfc, "WE", - wpt->longitude ); + lon ); } else if (strcmp(fmp->key, "LON_NMEA") == 0) { - writebuff(buff, fmp->printfc, degrees2ddmm(wpt->longitude)); + writebuff(buff, fmp->printfc, degrees2ddmm(lon)); } else /* DIRECTIONS *******************************************************/ if (strcmp(fmp->key, "LAT_DIR") == 0) { /* latitude N/S as a char */ writebuff(buff, fmp->printfc, - LAT_DIR(wpt->latitude)); + LAT_DIR(lat)); } else if (strcmp(fmp->key, "LON_DIR") == 0) { /* longitude E/W as a char */ writebuff(buff, fmp->printfc, - LON_DIR(wpt->longitude)); + LON_DIR(lon)); } else /* ALTITUDE CONVERSIONS**********************************************/ diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h index a69803e74..ef00a5963 100644 --- a/gpsbabel/csv_util.h +++ b/gpsbabel/csv_util.h @@ -60,7 +60,7 @@ void xcsv_ifield_add(char *, char *, char *); void -xcsv_ofield_add(char *, char *, char *); +xcsv_ofield_add(char *, char *, char *, int options); void xcsv_destroy_style(void); @@ -73,11 +73,14 @@ xcsv_get_char_from_constant_table(char *key); /****************************************************************************/ /* something to map fields to waypts */ +#define OPTIONS_NODELIM 1 +#define OPTIONS_ABSOLUTE 2 typedef struct field_map { queue Q; char * key; char * val; char * printfc; + int options; } field_map_t; /* a queuing struct for prologues / epilogues */ diff --git a/gpsbabel/style/README.style b/gpsbabel/style/README.style index 5ae8687eb..cbe384f19 100644 --- a/gpsbabel/style/README.style +++ b/gpsbabel/style/README.style @@ -164,12 +164,21 @@ IFIELDS are use as both input and output. The existence of OFIELDS is primarily to allow more flexible mapping of GPSBabel data to output data (say, for instance, to map the internal GPSBabel "description" variable to two or more fields on output). For all practical purposes, IFIELDS and -OFIELDS are defined the same way in the style file. +OFIELDS are defined the same way in the style file. The following options +are defined: + + o "no_delim_before" is supported on OFIELD tags to specify that this + field should be written without a field delimiter before it. It's + useful for limited field concatenation. + o "absolute" is supported on OFIELD tags for lat and lon to indicate + that only absolute values (never negative) are to be printed. + There are several different types of fields that may be defined. Each field consists of three pieces of information: the FIELD TYPE, a DEFAULT VALUE, and a PRINTF CONVERSION (for output). In many cases, not all pieces are used, -but all 3 pieces are required. +but all 3 pieces are required. Additionally, an fourth field is supported +that modifies the behaviour of the field being described. FIELDS should be defined in the style file in the logical order that they appear in the data, from left to right. This is the order in which they are diff --git a/gpsbabel/xcsv.c b/gpsbabel/xcsv.c index bbcffd75e..e74b184a7 100644 --- a/gpsbabel/xcsv.c +++ b/gpsbabel/xcsv.c @@ -330,6 +330,7 @@ xcsv_parse_style_line(const char *sbuff) } else if (ISSTOKEN(sbuff, "IFIELD")) { + int nodelim = 0; key = val = pfc = NULL; s = csv_lineparse(&sbuff[6], ",", "", linecount); @@ -367,6 +368,7 @@ xcsv_parse_style_line(const char *sbuff) * change the world on ifield vs ofield format later.. */ if (ISSTOKEN(sbuff, "OFIELD")) { + int options = 0; key = val = pfc = NULL; s = csv_lineparse(&sbuff[6], ",", "", linecount); @@ -386,6 +388,14 @@ xcsv_parse_style_line(const char *sbuff) /* printf conversion */ pfc = csv_stringtrim(s, "\"", 1); break; + case 3: + /* Any additional options. */ + if (strstr(s, "no_delim_before")) { + options |= OPTIONS_NODELIM; + } + if (strstr(s, "absolute")) { + options |= OPTIONS_ABSOLUTE; + } default: break; } @@ -393,7 +403,7 @@ xcsv_parse_style_line(const char *sbuff) s = csv_lineparse(NULL, ",", "", linecount); } - xcsv_ofield_add(key, val, pfc); + xcsv_ofield_add(key, val, pfc, options); } } } -- 2.30.2